" Vim syntax file
" Language:     haxe

" Please check :help haxe.vim for comments on some of the options available.

"set errorformat=%f\:%l\:\ characters\ %c-%*[^\ ]\ %m,%f\:%l\:\ %m
set errorformat=%f\:%l\:\ characters\ %c-%*[^\ ]\ %m,%f\:%l\:\ %m

" Quit when a syntax file was already loaded
if !exists("main_syntax")
  if version < 600
    syntax clear
  elseif exists("b:current_syntax")
    finish
  endif
  " we define it here so that included files can test for it
  let main_syntax='haxe'
endif

" don't use standard HiLink, it will not work with included syntax files
if version < 508
  command! -nargs=+ HaxeHiLink hi link <args>
else
  command! -nargs=+ HaxeHiLink hi def link <args>
endif

" some characters that cannot be in a haxe program (outside a string)
syn match haxeError "[\\@`]"
syn match haxeError "<<<\|=>\|<>\|||=\|&&=\|\*\/"

" use separate name so that it can be deleted in haxecc.vim
syn match   haxeError2 "#\|=<"
HaxeHiLink haxeError2 haxeError


" keyword definitions
syn keyword haxeExternal    import extern package
syn keyword haxeConditional if else switch
syn keyword haxeRepeat      while for do in
syn keyword haxeBoolean     true false
syn keyword haxeConstant    null
syn keyword haxeTypedef     this super
syn keyword haxeOperator    new cast 
syn keyword haxeType        Void Bool Int Float Dynamic
syn keyword haxeStatement   return
syn keyword haxeStorageClass    var final typedef enum
syn keyword haxeFunction    function
" syn keyword haxeStatic        
syn keyword haxeExceptions      throw try catch finally untyped
syn keyword haxeAssert      assert
syn keyword haxeMethodDecl      synchronized throws
syn keyword haxeClassDecl       extends implements interface
syn match   haxeOperator "\.\.\."
" to differentiate the keyword class from MyClass.class we use a match here
syn match   haxeTypedef     "\.\s*\<class\>"ms=s+1
syn match   haxeClassDecl       "^class\>"
syn match   haxeClassDecl       "[^.]\s*\<class\>"ms=s+1
syn keyword haxeBranch      break continue nextgroup=haxeUserLabelRef skipwhite
syn match   haxeUserLabelRef    "\k\+" contained
syn keyword haxeScopeDecl       static public protected private abstract override 

" haxe.lang.*
syn match haxeLangClass "\<System\>"
syn keyword haxeLangClass  Array BasicType Class Date DateTools EReg Hash IntHash IntIter Iterator Lambda List Math Md5 Reflect Std String StringBuf StringTools Xml XmlType
HaxeHiLink haxeLangObject            haxeConstant
syn cluster haxeTop add=haxeLangObject,haxeLangClass
syn cluster haxeClasses add=haxeLangClass

if filereadable(expand("<sfile>:p:h")."/haxeid.vim")
  source <sfile>:p:h/haxeid.vim
endif

if exists("haxe_space_errors")
  if !exists("haxe_no_trail_space_error")
    syn match   haxeSpaceError  "\s\+$"
  endif
  if !exists("haxe_no_tab_space_error")
    syn match   haxeSpaceError  " \+\t"me=e-1
  endif
endif

syn region  haxeLabelRegion     transparent matchgroup=haxeLabel start="\<case\>" matchgroup=NONE end=":" contains=haxeNumber,haxeCharacter
syn match   haxeUserLabel       "^\s*[_$a-zA-Z][_$a-zA-Z0-9_]*\s*:"he=e-1 contains=haxeLabel
syn keyword haxeLabel       default

" The following cluster contains all haxe groups except the contained ones
syn cluster haxeTop add=haxeExternal,haxeError,haxeError,haxeBranch,haxeLabelRegion,haxeLabel,haxeConditional,haxeRepeat,haxeBoolean,haxeConstant,haxeTypedef,haxeOperator,haxeType,haxeType,haxeStatement,haxeStorageClass,haxeAssert,haxeExceptions,haxeMethodDecl,haxeClassDecl,haxeClassDecl,haxeClassDecl,haxeScopeDecl,haxeError,haxeError2,haxeUserLabel,haxeLangObject


" Comments
syn keyword haxeTodo         contained TODO FIXME XXX
if exists("haxe_comment_strings")
  syn region  haxeCommentString    contained start=+"+ end=+"+ end=+$+ end=+\*/+me=s-1,he=s-1 contains=haxeSpecial,haxeCommentStar,haxeSpecialChar,@Spell
  syn region  haxeComment2String   contained start=+"+  end=+$\|"+  contains=haxeSpecial,haxeSpecialChar,@Spell
  syn match   haxeCommentCharacter contained "'\\[^']\{1,6\}'" contains=haxeSpecialChar
  syn match   haxeCommentCharacter contained "'\\''" contains=haxeSpecialChar
  syn match   haxeCommentCharacter contained "'[^\\]'"
  syn cluster haxeCommentSpecial add=haxeCommentString,haxeCommentCharacter,haxeNumber
  syn cluster haxeCommentSpecial2 add=haxeComment2String,haxeCommentCharacter,haxeNumber
endif
syn region  haxeComment      start="/\*"  end="\*/" contains=@haxeCommentSpecial,haxeTodo,@Spell
syn match   haxeCommentStar      contained "^\s*\*[^/]"me=e-1
syn match   haxeCommentStar      contained "^\s*\*$"
syn match   haxeLineComment      "//.*" contains=@haxeCommentSpecial2,haxeTodo,@Spell
HaxeHiLink haxeCommentString haxeString
HaxeHiLink haxeComment2String haxeString
HaxeHiLink haxeCommentCharacter haxeCharacter

syn cluster haxeTop add=haxeComment,haxeLineComment

if exists("haxe_haxedoc") || main_syntax == 'jsp'
  syntax case ignore
  " syntax coloring for haxedoc comments (HTML)
  " syntax include @haxeHtml <sfile>:p:h/html.vim
  " unlet b:current_syntax
  syn region  haxeDocComment    start="/\*\*"  end="\*/" keepend contains=haxeCommentTitle,@haxeHtml,haxeDocTags,haxeTodo,@Spell
  syn region  haxeCommentTitle  contained matchgroup=haxeDocComment start="/\*\*"   matchgroup=haxeCommentTitle keepend end="\.$" end="\.[ \t\r<&]"me=e-1 end="[^{]@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@haxeHtml,haxeCommentStar,haxeTodo,@Spell,haxeDocTags

  syn region haxeDocTags  contained start="{@\(link\|linkplain\|inherit[Dd]oc\|doc[rR]oot\|value\)" end="}"
  syn match  haxeDocTags  contained "@\(see\|param\|exception\|throws\|since\)\s\+\S\+" contains=haxeDocParam
  syn match  haxeDocParam contained "\s\S\+"
  syn match  haxeDocTags  contained "@\(version\|author\|return\|deprecated\|serial\|serialField\|serialData\)\>"
  syntax case match
endif

" match the special comment /**/
syn match   haxeComment      "/\*\*/"

" Strings and constants
syn match   haxeSpecialError     contained "\\."
syn match   haxeSpecialCharError contained "[^']"
syn match   haxeSpecialChar      contained "\\\([4-9]\d\|[0-3]\d\d\|[\"\\'ntbrf]\|u\x\{4\}\)"
syn match haxeEregEscape    contained "\(\\\\\|\\/\)"
syn region  haxeEreg        start=+\~\/+ end=+\/[gims]*+ contains=haxeEregEscape

syn region  haxeString      start=+"+ end=+"+ contains=haxeSpecialChar,haxeSpecialError,@Spell
syn region  haxeSingleString  start=+'+ end=+'+ 
" next line disabled, it can cause a crash for a long line
"syn match   haxeStringError      +"\([^"\\]\|\\.\)*$+
syn match   haxeCharacter    "'[^']*'" contains=haxeSpecialChar,haxeSpecialCharError
syn match   haxeCharacter    "'\\''" contains=haxeSpecialChar
syn match   haxeCharacter    "'[^\\]'"
syn match   haxeNumber       "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
"syn match   haxeNumber      "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
syn match   haxeNumber       "\(\<\d\+\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
syn match   haxeNumber       "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
syn match   haxeNumber       "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"


syn region haxeCondIf start="#if \+!\?" end="\W" skip="([A-Za-z0-9_ |&!]\+)"
syn region haxeCondElse start="#else \+!\?" end="\W" skip="([A-Za-z0-9_ |&!]\+)"
syn match haxeCondEnd "#end"
syn match haxeCondError "#else *$"

" unicode characters
syn match   haxeSpecial "\\u\d\{4\}"

syn cluster haxeTop add=haxeString,haxeCharacter,haxeNumber,haxeSpecial,haxeStringError

if exists("haxe_highlight_functions")
  if haxe_highlight_functions == "indent"
    syn match  haxeFuncDef "^\(\t\| \{8\}\)[_$a-zA-Z][_$a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=haxeType,haxeStorageClass,@haxeClasses
    syn region haxeFuncDef start=+^\(\t\| \{8\}\)[$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=haxeType,haxeStorageClass,@haxeClasses
    syn match  haxeFuncDef "^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=haxeType,haxeStorageClass,@haxeClasses
    syn region haxeFuncDef start=+^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=haxeType,haxeStorageClass,@haxeClasses
  else
    " This line catches method declarations at any indentation>0, but it assumes
    " two things:
    "   1. class names are always capitalized (ie: Button)
    "   2. method names are never capitalized (except constructors, of course)
    syn region haxeFuncDef start=+\s\+\(\(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*(+ end=+)+ contains=haxeType,haxeStorageClass,haxeComment,haxeLineComment,@haxeClasses
  endif
  syn match  haxeBraces  "[{}]"
  syn cluster haxeTop add=haxeFuncDef,haxeBraces
endif

if exists("haxe_mark_braces_in_parens_as_errors")
  syn match haxeInParen      contained "[{}]"
  HaxeHiLink haxeInParen    haxeError
  syn cluster haxeTop add=haxeInParen
endif

" catch errors caused by wrong parenthesis
syn region  haxeParenT  transparent matchgroup=haxeParen  start="("  end=")" contains=@haxeTop,haxeParenT1
syn region  haxeParenT1 transparent matchgroup=haxeParen1 start="(" end=")" contains=@haxeTop,haxeParenT2 contained
syn region  haxeParenT2 transparent matchgroup=haxeParen2 start="(" end=")" contains=@haxeTop,haxeParenT  contained
syn match   haxeParenError       ")"
HaxeHiLink haxeParenError       haxeError

if !exists("haxe_minlines")
  let haxe_minlines = 10
endif
exec "syn sync ccomment haxeComment minlines=" . haxe_minlines

" The default highlighting.
if version >= 508 || !exists("did_haxe_syn_inits")
  if version < 508
    let did_haxe_syn_inits = 1
  endif
  HaxeHiLink haxeFuncDef        Function
  HaxeHiLink haxeBraces     Function
  HaxeHiLink haxeBranch     Conditional
  HaxeHiLink haxeUserLabelRef   haxeUserLabel
  HaxeHiLink haxeLabel      Label
  HaxeHiLink haxeUserLabel      Label
  HaxeHiLink haxeConditional    Conditional
  HaxeHiLink haxeRepeat     Repeat
  HaxeHiLink haxeExceptions     Exception
  HaxeHiLink haxeAssert     Statement
  HaxeHiLink haxeStatic MoreMsg
  HaxeHiLink haxeStorageClass   StorageClass
  HaxeHiLink haxeMethodDecl     haxeStorageClass
  HaxeHiLink haxeClassDecl      StorageClass
  HaxeHiLink haxeScopeDecl      StorageClass
  HaxeHiLink haxeBoolean        Boolean
  HaxeHiLink haxeSpecial        Special
  HaxeHiLink haxeSpecialError   Error
  HaxeHiLink haxeSpecialCharError   Error
  HaxeHiLink haxeString     String
  HaxeHiLink haxeSingleString   String
  HaxeHiLink haxeEreg Special
  HaxeHiLink haxeEregEscape Special
  HaxeHiLink haxeCharacter      Character
  HaxeHiLink haxeSpecialChar    SpecialChar
  HaxeHiLink haxeNumber     Number
  HaxeHiLink haxeError      Error
  HaxeHiLink haxeStringError    Error
  HaxeHiLink haxeStatement      Statement
  HaxeHiLink haxeOperator       Operator
  HaxeHiLink haxeComment        Comment
  HaxeHiLink haxeDocComment     Comment
  HaxeHiLink haxeLineComment    Comment
  HaxeHiLink haxeConstant       Constant
  HaxeHiLink haxeTypedef        Typedef
  HaxeHiLink haxeTodo       Todo
  HaxeHiLink haxeLangClass      Special
  HaxeHiLink haxeFunction       Function

  HaxeHiLink haxeCommentTitle   SpecialComment
  HaxeHiLink haxeDocTags        Special
  HaxeHiLink haxeDocParam       Function
  HaxeHiLink haxeCommentStar    haxeComment

  HaxeHiLink haxeType       Type
  HaxeHiLink haxeExternal       Include

  HaxeHiLink htmlComment        Special
  HaxeHiLink htmlCommentPart    Special
  HaxeHiLink haxeSpaceError     Error

  HaxeHiLink haxeCondIf Macro
  HaxeHiLink haxeCondElse Macro
  HaxeHiLink haxeCondEnd Macro
  HaxeHiLink haxeCondError Error
endif

delcommand HaxeHiLink

let b:current_syntax = "haxe"

if main_syntax == 'haxe'
  unlet main_syntax
endif

let b:spell_options="contained"

" vim: ts=8

